package ModelLayer;

import java.util.ArrayList;
import java.util.Date;
/**
 * Holds information of Order objects, designed as a regular class.
 *
 * @author  Danny M.P., Jakob K., Anna K., Anders A.P., Mie P.  
 * @version 1.0
 */
public class Order {

    private ArrayList<OrderLine> orderLines;
    private Customer             customer;
    private Employee             employee;
    private static int           counter;
    private int                  orderNo;
    private Date                 orderDate,
                                 packingDate,
                                 deliveryDate;
    private double               totalPrice;
    private boolean              isOffer,
                                 packing,
                                 delivery,
                                 isComplete,
                                 isPaid;

    /**
     * Construcs an instance of Order, taking no parameters.
     */
    public Order() {

        this.orderLines = new ArrayList<OrderLine>();
        this.orderDate = new Date();
        this.packingDate = this.orderDate;
        this.deliveryDate = this.orderDate;

        setTotalPrice();        

        ++this.counter;
        orderNo = counter;

    }

    /**
     * Sets the total price of the order, by accumulating line prices.
     */
    private void setTotalPrice() {

        double var = 0.0;
        for (OrderLine ol : orderLines) {
            var += ol.getLinePrice();
        }
        this.totalPrice = var;

    }

    /**
     * Associates a given Customer object to the Order object.
     *
     * @param   c   a Customer object.
     */ 
    private void addCustomer(Customer c) {

        this.customer = c;
    
    }

    /**
     * Associates a given Employee object to the Order object.
     *
     * @param   e   an Employee object.
     */
    public void addEmployee(Employee e) {

        this.employee = e;

    }

    /**
     * Adds an OrderLine object to the Order object's orderLine collection.
     *
     * @param   ol  an OrderLine object.
     */
    public void addOrderLine(OrderLine ol) {

        this.orderLines.add(ol);

    }

    /**
     * Effectively ends the order process and returning the total price for the order.
     *
     * @return  totalPrice  the total accumulated price of the Order object.
     */
    public double endOrder() {

        setTotalPrice();
        this.isComplete = true;
        return this.totalPrice;

    }

    /**
     * Registers a customer's payment.
     *
     * @param   payment     the amount payed by the customer.
     * @return  cashBack    returns the amount the customer is to receive back.
     * @throw   Exception   if the payment is insufficient.
     */
    public double registerPayment(double payment) {

        if (payment - totalPrice >= 0) {
            this.isPaid = true;
            double cashBack = payment - totalPrice;
            return cashBack;
        }
        else {
            throw new IllegalArgumentException();
        }

    }

    /**
     * Updates the order information, taking the following parameters:
     *
     * @param   c           a Customer object.
     * @param   packing     a boolean value stating wether the customer needs packing of the order.
     * @param   delivery    a boolean value stating wether the customer needs delivery of the order.
     */
    public void updateOrder(Customer c, boolean packing, boolean delivery) {

        addCustomer(c);
        this.packing = packing;
        this.delivery = delivery;

    }
    
    /**
     * Returns the totalPrice field to the caller.
     *
     * @return  totalPrice  the total price of the order.  
     */
    public double getTotalPrice() {

        setTotalPrice();
        return this.totalPrice;

    }

    /**
     * Returns the orderNo field to the caller.
     *
     * @return  orderNo  the order number.  
     */    
    public int getOrderNo() {

        return orderNo;

    }

    /**
     * Returns the orderDate field to the caller.
     *
     * @return  orderDate  the order's creation date.  
     */
    public String getOrderDate() {

        return orderDate.toString();

    }

    /**
     * Sets a value of the isOffer field.
     *
     * @param   state   a boolean value stating wether the order is an offer or not.
     */    
    public void setIsOffer(boolean state) {

        this.isOffer = state;

    }

    /**
     * Returns the orderLines collection to the caller.
     *
     * @return  orderLines  the collection of orderLines.  
     */    
    public ArrayList<OrderLine> getOrderLines() {

        return orderLines;

    }

    /**
     * Deletes an OrderLine object from the orderLines collection.
     *
     * @param  ol  an OrderLine object.  
     */    
    public void removeOrderLine(OrderLine ol) {

        orderLines.remove(ol);

    }

    /**
     * Returns the Customer object associated with the order to the caller.
     *
     * @return  customer  the Customer object associated with the order.  
     */    
    public Customer getCustomer() {

        return customer;

    }

    /**
     * Returns the isOffer field to the caller.
     *
     * @return  isOffer  a boolean value stating wether the order is an offer or not.  
     */    
    public boolean getIsOffer() {

        return isOffer;

    }

}